% optprog.sty
% <14 Apr 93> Bob Bowerman (bowerman@dial.uwaterloo.ca)
%
% This file defines the optprog environment and is just a hacked up
% version of the eqnarray environment designed for use with optimization
% problems. Instead of just 3 columns optprog lays out 7 columns set up as
% follows:  rrcllll. The overall environment is set in displaystyle with
% the first column being defined as normal text. The first column is
% intended for text associated with the specification of the optimization
% program such as `Minimize' or `subject to'. The second, third, and fourth
% columns are intended for the lhs, operator, and rhs of the constraints.
% The fifth, sixth, and seventh columns are intended for defining the range
% for the indices of the constraints. The columns are centred between the
% left and right margins and both the objective function and the
% constraints are numbered.
% 
% As well several utility macros are defined.
%  \objective{#1} Typesets the objective function. Left
%     aligns the objective function over the last 6 columns.
%  \optaction[#2]{#1} Sets #2 in mathmode underneath #1 which is shown in
%  text, e.g. \optarg[x_i]{Mimimize} puts $x_i$ directly underneath Minimize
%
% The optprog* environment is defined which does not include
% equation numbers. As well, \nonumber suppresses the equation number for
% a single line.
%
% Here is an example of its usage on a LP:
%  \begin{optprog}
%  \optaction[x_i]{Maximize} & \objective{Z = \sum_{j=1}^n c_j x_j} \label{obj}\\
%  subject to & \sum_{j=1}^n a_{ij} x_j & \leq & b_i & i=1\ldots{}m \label{cons1} \\
%  and        & x_i & \geq & 0 & j=1\ldots{}n \label{cons2} 
%  \end{optprog}

\immediate\write\sixt@@n{Optprog Environment defined <14 Apr 93>}

\chardef\f@ur=4
\chardef\f@ve=5
\chardef\s@x=6

\def\@optprog{\stepcounter{equation}\let\@currentlabel\theequation
\global\@eqnswtrue\m@th
\global\@eqcnt\z@\tabskip\@centering\let\\\@prbspcr
$$\halign to\displaywidth\bgroup
  \hfil\hskip\@centering \hbox{\tabskip\z@{##}}&
  \global\@eqcnt\@ne\hskip 2\arraycolsep \hfill\hskip\@centering $\displaystyle\tabskip\z@{##}$&
  \global\@eqcnt\tw@\hskip \arraycolsep \hfill${##}$\hfill&
  \global\@eqcnt\thr@@\hskip \arraycolsep
      $\displaystyle\tabskip\z@{##}$&
  \global\@eqcnt\f@ur\hskip 2\arraycolsep
      $\displaystyle\tabskip\z@{##}$&
  \global\@eqcnt\f@ve\hskip 2\arraycolsep
      $\displaystyle\tabskip\z@{##}$&
  \global\@eqcnt\s@x\hskip 2\arraycolsep
      $\displaystyle\tabskip\z@{##}$\hfil\tabskip\@centering&
  \llap{##}\tabskip\z@\cr}
 
\def\endoptprog{\@@prbspcr\egroup
      \global\advance\c@equation\m@ne$$\global\@ignoretrue}
 
\def\objective#1{\multispan{6} \global\@eqcnt\s@x\hskip \arraycolsep
      $\displaystyle\tabskip\z@{#1}$\hfil\tabskip\@centering}

\def\optaction[#1]#2{\mbox{$\displaystyle\mathrel{\mathop{\hbox{#2}}\limits_{\textstyle#1}}$}}
 
\def\@prbspcr{{\ifnum0=`}\fi\@ifstar{\global\@eqpen\@M
    \@yprbspcr}{\global\@eqpen\interdisplaylinepenalty \@yprbspcr}}
 
\def\@yprbspcr{\@ifnextchar [{\@xprbspcr}{\@xprbspcr[\z@]}}
 
\def\@xprbspcr[#1]{\ifnum0=`{\fi}\@@prbspcr
   \noalign{\penalty\@eqpen\vskip\jot\vskip #1\relax}}
 
\def\@@prbspcr{\let\@tempa\relax
    \ifcase\@eqcnt \def\@tempa{& & & & & &}\or \def\@tempa{& & & & & &} 
      \or \def\@tempa{& & & & &} \or \def\@tempa{& & & &}
      \or \def\@tempa{& & &} \or \def\@tempa{& &}
      \else \def\@tempa{&}\fi
     \@tempa \if@eqnsw\@eqnnum\stepcounter{equation}\fi
     \global\@eqnswtrue\global\@eqcnt\z@\cr}
 
% Here's the optprog* environment:
 
\let\@sprbspcr=\@prbspcr
\@namedef{optprog*}{\def\@prbspcr{\nonumber\@sprbspcr}\optprog}
\@namedef{endoptprog*}{\nonumber\endoptprog}

\def\optprog{\@ifnextchar [{\@optprog1}{\@optprog}}